Skip to content

doc: describe the nvx package's build, release packages and setup (SL6.10e) - #1546

Merged
Pedro Henrique Penna (ppenna) merged 3 commits into
feature/nvx-refactorfrom
agents/slim-sl6-10e-build-docs
Nov 13, 2026
Merged

Pedro Henrique Penna (ppenna) merged 3 commits into
feature/nvx-refactorfrom
agents/slim-sl6-10e-build-docs

Conversation

@ppenna

@ppenna Pedro Henrique Penna (ppenna) commented Nov 12, 2026 •

Copy link
Copy Markdown
Contributor

Part of #1131 (SL6.10e, "Developers can build and package NVX"). Parent #1090, umbrella #1076.

What and why

The build, distribution, project-structure, guest and setup docs now describe the single nvx package as nvx-rs/Cargo.toml, Cargo.lock, scripts/ and the packaging workflows define it at the final feature/nvx-refactor tip (12a90c4a0ee, after every code slice of #1076). They also stop describing what SL7.8b (#1534) and SL7.8c (#1536) deleted. No script, package, profile, cache or provenance changes.

Stale text (doc: drop the deleted sandbox bootstrap from the build and guest docs):

  • doc/build.md's Alpine paragraph said that the initramfs includes "the sandbox PID-1 bootstrap and its container namespace scripts", and that the APK manifest records the tools "used by the bootstrap". It now says that nvx-rs sandbox boots the Alpine initramfs, whose /init hands PID 1 to nvx-init when the command line has nvx_sandbox=1. It also says that the APK manifest records every package, among them the five that AlpineBuildConstants.PACKAGES adds.
  • doc/guests/ubuntu-guest.md named "the Alpine control initramfs and its init agent" as the distro layer's boot supervisor; that is now nvx-init. It also described the cgroups and namespaces "that the sandbox uses", which no sandbox code uses any more.
  • doc/project-structure.md credited the common scripts with shutdown and the time ABI, which the Rust binaries took over. It now says what each script does.

The package (doc: describe the nvx package's features, profiles, and binaries):

  • doc/build.md gains The nvx package:

    • why the package has its own lockfile, and that NVX's builds pass --locked;
    • fixed tables of its five features, of the profiles that NVX's builds use (with the guest profile's settings), of its binaries (feature, profile and target, builder, and where each ships), and of its build outputs;
    • its caches: Cargo's target directories and registry, the guest routine's fresh target directory, which keeps RUSTC_WRAPPER, the self-hosted runners' sccache, and CI's guest image keys on the package's guest inputs, which it lists as GuestRustBuildConstants selects them;
    • its three provenance records;
    • its license inputs, nvx-rs/LICENSE, the lockfile and THIRD_PARTY_NOTICES.md, with the unit tests that keep them consistent.
  • doc/build.md gains Release packages, the binary matrix of the linux-kvm, linux-mshv and windows-whp packages:

    • the OpenVMM and nvx-rs build of each, the guest artifacts that each ships, the sandbox scratch template among them, and the archive;
    • it links doc/ci.md's Release packages section (SL6.10f, doc: describe the final gates, test owners, packaging and publishing (SL6.10f) #1540) for the package jobs rather than repeating them;
    • the existing paragraphs on what packaging needs, SOURCE-MANIFEST.json and the release layout now fall under it, unchanged.
  • doc/distribution.md links both sections and leaves the package jobs' details to doc/ci.md. It adds the guest binaries and the crate's own license to its licensing paragraph, says what the crate holds, and documents installing the guest tools from the crate:

    cargo install nvx --version VERSION --locked \
      --no-default-features --features guest --profile guest \
      --target x86_64-unknown-linux-musl --bin nvx-ingress

    It says why each option is there: --version, because every published version is a pre-release; --target, for the static executables that NVX's images hold.

  • doc/project-structure.md lists:

    • the package's files (Cargo.toml, Cargo.lock, LICENSE, README.md) and its top-level modules;
    • what the slimming made private to the crate: the CLI's export planner, egress policy compiler and sandbox launch profile, the error codes, the guest's space, and the platform layer;
    • what each binary calls;
    • guest_binaries.py and guest_artifact_reuse.py;
    • what build/, .cache/ and nvx-rs/target/ hold.

    The Ubuntu and Azure Linux pages name the package's guest inputs, link the release packages, and point to the scratch template.

Setup (setup: describe the Python runner-setup package and the nvx-rs build):

  • scripts/setup/README.md describes nvx_azure, the existing standard-library Python package with which NVX's Azure scale-set instances provision themselves as runners through these scripts. It also says that a build check builds nvx-rs from the package, records its provenance and dry-runs it.
  • scripts/setup/azure/README.md, the runner-provisioning guide, gains a fixed table of the package's six commands: what runs each (the systemd units, the runner service's ExecStartPre, the Custom Script shim and the Nvx-Setup-GitHub-Runner task) and the step that each takes.
  • doc/project-structure.md lists scripts/setup/README.md and the azure/ tree.

Coordination. The kernel-configuration inventory and the kernel configuration checks table keep the text that SL6.11b (#1542) gave them; the rebase onto 12a90c4a0ee had no conflict. This PR touches none of the documents that SL6.10f (#1540) or SL6.10d owns, nor the migration guide (SL6.10h).

Noticed, out of scope:

  • nvx-rs/README.md's Features section still lists exec; the orchestrator has passed that to SL6.10a.
  • doc/project-structure.md's tree omits benchmark_host.py, microvm_shards.py, shard_plans.py and the nfv-* workflows, which are not package paths.

Size

Core lines Counted files
Estimate (#1131) 0 (docs) none
Measured 0 0

Only Markdown changes: the seven named documents.

Old tests of the area

None changes: the PR changes no test, CI step or doc test, and the case matrix keeps every row.

Test changes

python scripts\check_test_changes.py --base origin/feature/nvx-refactor: 0 change(s) to existing tests, so no tests-modified.

Validation

local_gates.py --files with the seven files (from dev, since this branch has no copy) selects test-changes, markdown-links, test-layout and nvx-cli (validate-nvx). I ran them from this branch's definitions on Windows. The table shows the results on the head rebased onto 12a90c4a0ee:

Check Result
python scripts\nvx.py verify passed
python scripts\check_markdown_links.py passed
python scripts\check_test_layout.py passed
python scripts\check_test_changes.py --base origin/feature/nvx-refactor 0 changes
SL5.2's check_matrix.py <worktree> 99d2022085f passed
The doc and setup tests: python -m unittest scripts/test_tool_versions.py scripts/test_markdown_links.py scripts/test_setup_azure.py scripts/test_setup_azure_linux.py scripts/test_setup_azure_windows.py passed: 263 tests, 3 skipped
validate-nvx's Windows commands: compileall, its unittest list, test_adversarial.py, test_hosts.py and nvx.py's --help checks passed: 1803 tests, 73 skipped; 84, 11 skipped; 4
The nvx.py commands that the docs name: build-guest-binaries, check-guest-binaries, test-guest-binaries, record-nvx-rs-provenance, guest-binary-source-identity, check-static-elf, build-scratch-template, package and archive-release --help all exist with the options named
nvx_azure's cli.main(['--help']) lists exactly the six commands of the table

On nvx-mshv-test (Azure Linux 3, Rust 1.95.0, at 04fbbd480bf). Since then the base changed none of nvx-rs/Cargo.toml, Cargo.lock, src/bin/, the build, release and setup scripts, or the packaging workflows.

Command Result
cargo build --locked --no-default-features --features guest --profile guest in nvx-rs/ finished the guest profile
cargo install --locked --path nvx-rs --no-default-features --features guest --profile guest --bin nvx-ingress --root DIR installed a stripped, dynamically linked nvx-ingress, which prints its usage and exits 2
the same with --target x86_64-unknown-linux-musl; with --bins a static-pie nvx-ingress (check-static-elf); all ten guest binaries
cargo install nvx --locked --no-default-features --features guest --profile guest --bin nvx-ingress fails: could not find nvx in registry crates-io with version *, as the docs say
cargo install nvx --version 0.1.0-alpha.16 --locked --no-default-features --features guest --profile guest --target x86_64-unknown-linux-musl --bin nvx-ingress built the guest profile and installed a static-pie nvx-ingress
rustup target add x86_64-unknown-linux-musl up to date
cargo build --release --locked --features cli --manifest-path nvx-rs/Cargo.toml --target-dir nvx-rs/target, then record-nvx-rs-provenance built; the provenance has format, source_sha256, toolchain, target, features: ["cli"], executable_sha256
the same with --target x86_64-unknown-linux-musl, as CI builds it static-pie at nvx-rs/target/x86_64-unknown-linux-musl/release/nvx-rs
python3 scripts/nvx.py build-guest-binaries --output build/guest-binaries ten static-pie binaries; manifest.json holds toolchain, target, profile, source_sha256 and binaries; its source_sha256 equals guest-binary-source-identity; the .guest-binaries.work-* directory is gone

Review findings, all fixed:

  • A code-review subagent checked every changed claim against the manifest, the scripts and the workflows, first at 04fbbd480bf and again at 12a90c4a0ee. It found three problems at the first base: the error types of the featureless library, the profiles table's scope, and the dep-info exemption of generated files. At the tip it found one more: linux-bootstrap runs the MSHV check only for backend: mshv with kernelMode: azurelinux-mshv.
  • Copilot's one thread was that the self-hosted runners compile through a persistent sccache, which the guest routine's environment keeps.

Not run: no microVM scenario, since only documentation changes. The change is documentation-only, so CI runs only its GitHub-hosted jobs.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues are reported for the documentation updates aligning the guides with the single nvx package.

No open issues 🎉

What changed in this PR

This documentation-only PR advances #1131 by aligning the build, distribution, project layout, guest-image, and setup guides with the single nvx package. It changes no build or runtime behavior.

Changes:

  • Documents package features, profiles, binaries, outputs, caches, provenance, licenses, and platform release contents.
  • Adds guest-tool installation instructions and replaces obsolete sandbox-bootstrap descriptions.
  • Describes the Azure runner-setup Python package and its provisioning commands.
File Description
scripts/​setup/​README.md Explains Azure provisioning and setup-time CLI builds and provenance.
scripts/​setup/​azure/​README.md Lists the six provisioning commands, their callers, and responsibilities.
doc/​project-structure.md Updates package, module, setup, and generated-output descriptions.
doc/​guests/​ubuntu-guest.md Updates boot supervision, guest inputs, and scratch-template references.
doc/​guests/​azurelinux-guest.md Clarifies guest-input provenance and links release packaging details.
doc/​distribution.md Documents package contents, licensing, and guest-tool installation.
doc/​build.md Adds package and release matrices and updates Alpine boot documentation.

Review effort: Balanced

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The cache inventory needs to distinguish uncached Cargo target trees from the persistent shared sccache, which can reuse earlier compilations even with a fresh target directory.

1 open issue

Review effort: Balanced

Comment thread doc/build.md Resolved

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues remain for the documentation updates aligning the guides with the single nvx package.

No open issues 🎉

1 resolved since last review

Review effort: Balanced

SL7.8b (#1534) deleted the old layered init, nvx-init-agent, with the
managed agent's sandbox mode, and SL7.8c (#1536) deleted the Alpine
one-shot container helpers. The build guide still said that the Alpine
initramfs includes "the sandbox PID-1 bootstrap and its container
namespace scripts", that the kernel checks cover what "the sandbox
bootstrap" needs, and that the APK manifest records the tools "used by
the bootstrap". The Ubuntu guest still named "the Alpine control
initramfs and its init agent" as the boot supervisor of the distro
layer, and the cgroups and namespaces "that the sandbox uses". The
project structure still credited the common scripts with shutdown and
the time ABI, which the Rust guest binaries took over.

Say instead what the code does now:

- the Alpine initramfs is the one that nvx-rs sandbox boots, and with
  nvx_sandbox=1 the common /init hands PID 1 to nvx-init (exec
  /sbin/nvx-init in guest/common/init), which initializes the
  sandbox's layered root and serves its managed control session;
- the APK manifest records every package of the image, among them the
  five that AlpineBuildConstants.PACKAGES adds to the minirootfs;
- nvx-init supervises the Ubuntu distro layer, and the kernel provides
  the memory and process-count cgroups and the PID, mount, UTS and
  network namespaces for the guest's programs, without claiming that
  the sandbox uses them;
- the common scripts mount the host share (nvx-hostmount), prepare the
  guest for a snapshot and repair its restores (nvx-snapshot), and
  probe for the tests and benchmarks; the Rust binaries provide PID 1,
  the time ABI's guest side, shutdown and the rest.

The kernel inventory and its checks table keep the text that SL6.11b
(#1542) gave them.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The build, distribution, and structure docs described the nvx crate
only in passing: none listed its features, its Cargo profiles, or which
of its binaries each build makes and where each ships; the guest docs
spoke of an "aggregate nvx-rs source digest" without saying which files
it covers; no document said how a guest that NVX does not build gets
the guest tools; and the structure still credited the crate with
artifact discovery, which SL6.4 (#1533) and SL6.6b made private to the
CLI or deleted.

Build gains two sections, traced to nvx-rs/Cargo.toml, Cargo.lock,
scripts/nvx_tools/{guest_binaries,nvx_rs,release,build_constants}.py,
ci.yml, package-platform.yml and the package-release action:

- The nvx package: the one package, why it has its own lockfile, that
  NVX's builds pass --locked and the crate ships the lockfile; fixed
  tables of its five features and of its profiles, with the guest
  profile's settings, and of its binaries, with the feature, profile,
  target, builder and destination of each; its outputs; its caches:
  Cargo's target directories and registry, the guest routine's fresh
  target directory, which keeps RUSTC_WRAPPER, the sccache cache of
  the self-hosted runners, and CI's guest image keys on the guest
  inputs, which it lists as GuestRustBuildConstants selects them; its
  three provenance records; and its license inputs, nvx-rs/LICENSE, the
  lockfile and THIRD_PARTY_NOTICES.md, which the unit tests keep in
  step.
- Release packages: the binary matrix of CI's three packages, the
  OpenVMM and nvx-rs build of each, the guest artifacts that each
  ships, the sandbox scratch template among them, and the archive,
  with a link to Continuous integration's Release packages section,
  which describes the package jobs.

Distribution links them, leaves the package jobs' mechanics to that
section of Continuous integration, adds the guest binaries and the
crate's own license to its licensing paragraph, says what the crate
holds, and documents installing the guest tools from the crate with
cargo install nvx --version VERSION --locked --no-default-features
--features guest --profile guest --target x86_64-unknown-linux-musl,
with why each option is there. The structure lists the package's
files, Cargo.toml, Cargo.lock, LICENSE and README.md, its top-level
modules, with what is private to the crate since SL6.5a2, SL6.7b,
SL6.8c, SL6.13b and SL6.14 (the CLI's export planner, egress policy
compiler and sandbox launch profile, the error codes, the guest's
space, the platform layer), and what each binary calls,
guest_binaries.py and guest_artifact_reuse.py, and what build/,
.cache/ and nvx-rs/target/ hold. The Ubuntu and Azure Linux guests
name the package's guest inputs, link the release packages, and point
to the scratch template.

Evidence, on nvx-mshv-test (Azure Linux 3, Rust 1.95.0) at 04fbbd4:
cargo build --no-default-features --features guest --profile guest
finished the guest profile; cargo install --path nvx-rs and
cargo install nvx --version 0.1.0-alpha.16 with the documented options
installed nvx-ingress as a static-pie executable, which prints its
usage and exits 2; without --target it is dynamic, and without
--version cargo install finds no version; --bins installs all ten.
build-guest-binaries wrote a manifest whose source_sha256 equals
guest-binary-source-identity, and removed its work directory.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
The setup guide pointed to "Azure provisioning" without saying what it
holds, and the structure did not list scripts/setup/azure at all,
although nvx_azure, the standard-library Python package that the
instances of NVX's CI scale sets run to provision themselves as
runners, has replaced their shell bootstrap since October. The Azure
guide described the package's modules, but not the commands that its
cli.py takes or what runs each. And the guide's build checks said only
that they validate "the command that NVX generates", although both
setup scripts build nvx-rs from the nvx package, record its
provenance, and dry-run it.

- scripts/setup/README.md says what the package does, through which
  scripts, with which credential, and how build_package.py packages
  it, and that a build check builds nvx-rs with the command of Usage,
  records its provenance, and checks nvx-rs run --dry-run.
- scripts/setup/azure/README.md gains a fixed table of the package's
  six commands, linux-bootstrap, linux-block-metadata,
  linux-refresh-metadata, linux-verify-mshv, windows-stage and
  windows-bootstrap, with the unit, task or shim that runs each, from
  build_package.py, linux_bootstrap.py, windows_stage.py and
  windows_system.py, and the step that each takes.
- doc/project-structure.md lists scripts/setup/README.md and the
  azure/ tree, and describes the package beside the setup scripts.

Evidence: python -c "...cli.main(['--help'])" lists exactly these six
commands, and the guides' offline validation, test_setup_azure,
test_setup_azure_linux, test_setup_azure_windows and
test_tool_versions, passes on Windows, as does the link check.

Part of #1131 (SL6.10e).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

No active review issues were identified for the documentation updates aligning the guides with the single nvx package.

No open issues 🎉

Review effort: Balanced

@ppenna
Pedro Henrique Penna (ppenna) merged commit e6c65b9 into feature/nvx-refactor Nov 13, 2026
80 of 83 checks passed
@ppenna
Pedro Henrique Penna (ppenna) deleted the agents/slim-sl6-10e-build-docs branch November 13, 2026 00:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants